package com.qianfeng.exam.service.impl;

import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.qianfeng.exam.cache.AuthorsCache;
import com.qianfeng.exam.cache.BookCache;
import com.qianfeng.exam.cache.CategoryCache;
import com.qianfeng.exam.constants.ResultCode;
import com.qianfeng.exam.dto.BooksDto;
import com.qianfeng.exam.event.BookCacheChangeEvent;
import com.qianfeng.exam.exceptions.AddDataException;
import com.qianfeng.exam.mapper.BookMapper;
import com.qianfeng.exam.pojo.Authors;
import com.qianfeng.exam.service.IBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class BookServiceImpl implements IBookService {
    @Autowired
    private BookMapper bookMapper;
    @Autowired
    private BookCache bookCache;
    @Autowired
    private AuthorsCache authorsCache;
    @Autowired
    private CategoryCache categoryCache;
    @Autowired
    private ApplicationContext context;
    @Autowired
    private BookCacheChangeEvent event;
    @Override
    public void addBook(BooksDto books) {
        //判断用户有没有输入数据
        if (books==null || books.isNull()){
            throw new AddDataException("数据不能为空", ResultCode.BOOK_NAME_ISNULL);
        }
        //判断该书籍是否已经在数据库中存在
        BooksDto obj = bookCache.getObj(books.getBookName());
        if (obj != null){
            throw new AddDataException("该书籍已经存在", ResultCode.FAIL);
        }
        bookMapper.addBook(books);

        context.publishEvent(event);

    }

    @Override
    public PageInfo<BooksDto> findAllDevice(int pageNum, int pageSize, String name) {
        PageInfo<BooksDto> pageInfo =null;
        List<BooksDto> booksList = bookCache.getAllDate();
        List<BooksDto> realBookList = booksList.stream().filter(books -> {
            boolean isFetchName = true;
            boolean isFetchAuthorname = true;
            String bookName1 = books.getBookName();//每一个书的名字
            Long authorId = books.getAuthorId();//每一个角色id
            if (!StringUtil.isEmpty(name)) {//如果用户输入了 name 条件

                Authors obj = authorsCache.getObj(authorId);//每一个作者
                isFetchName = bookName1.contains(name); //每个数据库中的书名和输入的书进行比较
                isFetchAuthorname = obj.getAuthorName().contains(name); //每个数据库中的作者和 输入的作者进行比较
                System.out.println(obj.getAuthorName()+"+++++++++++++"+name+"+++++++++"+isFetchAuthorname);
            }
            books.setCategory(categoryCache.getObj(books.getCategoryId()));
            books.setAuthor(authorsCache.getObj(books.getAuthorId()));
            System.out.println(isFetchAuthorname+"-------------"+isFetchName);
            return isFetchName || isFetchAuthorname;

        }).collect(Collectors.toList());//过滤出来了符合条件的


        //判断越界问题
        int last_index= pageSize;//防止第一页没有数据,给一个默认值

        if (pageNum * pageSize >= realBookList.size()){//页码*页大小=当前页最后一条 >= 总条数
            //说明在,且最后一页没有没占满,最后一页的截取下标就是-->最后一页的起始行~总条数
            last_index = realBookList.size();
        }else {
            //说明不在最后1页 整页都有数据,截取的下标为当前页起始行~当前页最后一条  截的下标含头不含尾
            last_index = pageNum * pageSize;
        }
        //  (3-1)*5=10 =第2页第一行(不+1是因为下标0开始)
        //(页码-1)*页大小=当前页起始行
        if ((pageNum-1)*pageSize >= realBookList.size()){
            //说明查询页的起点超过总数据范围了,返回空值,防止数据下标越界
            pageInfo = new PageInfo<>();
            return pageInfo;
        }

        //切割集合
        //这些都是为了不访问数据库影响资源, 而在对缓存做逻辑操作,减少了数据库服务器的访问次数,节省了磁盘的IO消耗

        //集合的切割 第一页: (1-1)*10,10  截取的数据为从下标 0 到 9 的数据 共10条
        List<BooksDto> subList = realBookList.subList((pageNum - 1) * pageSize, last_index);
        pageInfo = new PageInfo<>(subList);
        ////设置总条数给前端使用 --> 即为符合条件的集合长度
        pageInfo.setTotal(realBookList.size());
        System.out.println(pageInfo.getList().toString());
        return pageInfo;
    }

}
